package g

import "fmt"

/*
 * @lc app=leetcode.cn id=38 lang=golang
 *
 * [38] 外观数列
「外观数列」是一个整数序列，从数字 1 开始，序列中的每一项都是对前一项的描述。前五项如下：
1.     1               6. 312211
2.     11              7. 13112221
3.     21              8. 1113213211
4.     1211            9. 31131211131221
5.     111221          10.13211311123113112211
1 被读作  "one 1"  ("一个一") , 即 11。
11 被读作 "two 1s" ("两个一"）, 即 21。是对11的描述
21 被读作 "one 2",  "one 1" （"一个二" ,  "一个一") , 即 1211。是对21的描述
1211 被读作 "one 1" "one 2" "two 1"(一个一，一个二，二个一)，既111221。是对1211的描述

给定一个正整数 n（1 ≤ n ≤ 30），输出外观数列的第 n 项。

你可以将其视作是由递归公式定义的数字字符串序列：

countAndSay(1) = "1"
countAndSay(n) 是对 countAndSay(n-1) 的描述，然后转换成另一个数字字符串。

注意：整数序列中的每一项将表示为一个字符串。
*/

// @lc code=start
func countAndSay(n int) string {
	if n == 1 {
		return "1"
	}
	l := []int{1}
	for i := 0; i < n-1; i++ { // 除去1，遍历n-1次
		l = say(l)
	}
	result := ""
	for i := 0; i < len(l); i++ {
		result += fmt.Sprintf("%v", l[i])
	}
	return result
}

// 基本思路就是统计相同元素个数size+value塞到新的list中(lnew),循环执行
func say(vals []int) []int {
	var newVals []int
	size := 0
	lastVal := vals[0]
	for _, val := range vals {
		if val == lastVal { // 相同+1
			size++
		} else {
			newVals = append(newVals, size, lastVal)
			size = 1
			lastVal = val
		}
	}
	newVals = append(newVals, size, lastVal) // 最后一次统计
	return newVals
}

// @lc code=end
